import { ConfigureService } from '@app/configure';
import { DbService } from '@app/db';
import { Member } from '@app/db/common/entities/Member';
import { JwtVerifyService } from '@app/jwt-verify';
import {Injectable } from '@nestjs/common';
import { createHash, randomUUID } from 'node:crypto'

@Injectable()
export class AuthService {
    constructor(
        public readonly db:DbService,
        public readonly jwt:JwtVerifyService,
        public readonly config:ConfigureService
    ) {}

    generateSalt() {
        return randomUUID().split('-').pop().toLocaleLowerCase()
    }

    buildPassword(password:string, salt:string) {
        password = createHash('sha256').update(password + salt).digest('hex').toLowerCase()
        return createHash('sha256').update(password + salt).digest('hex').toLowerCase()
    }

    async verify(account:string, password:string, tenantId:number = 0) : Promise<Member>{
        
        const member = await this.db.member.findOne({account : account, tenantId : tenantId}, ['name', 'password', 'id', 'salt', 'belong', 'super', 'enable'])
        if(!member || this.buildPassword(password, member.salt) != member.password) {
            return null
        }

        return member
    }

    updateLogin(id:number, time:number, ip:string) {
        this.db.member.update(id, {lastLoginTime : time})
    }

    makeToken(id:number, time?:number, jwtConfig?:any) {
        if(!time) {
            time = Math.floor((new Date()).getTime() / 1000)
        }

        if(!jwtConfig) {
            jwtConfig = this.config.get('jwt.admin')
        }


        let payload = {key : id * jwtConfig.login.scale + jwtConfig.login.scale, id : Math.ceil((time - 1030) / 263), time : time}
        let accessToken = this.jwt.sign(payload, {
            secret : jwtConfig.login.secret,
            expiresIn : jwtConfig.expire
        })

        let refreshToken = this.jwt.sign({key :id  * jwtConfig.refreshLogin.scale - jwtConfig.refreshLogin.scale, rid : Math.ceil((time - 8030) / 463), time : time}, {
            secret : jwtConfig.refreshLogin.secret,
            expiresIn : jwtConfig.expire
        })

        return {
            accessToken,
            refreshToken,
            expire : jwtConfig.expire
        }
    }
}
